package com.wn.sddfp.gateway.config.black;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

@Component
public class BlackIpGlobalFilter implements GlobalFilter, Ordered {

    @Resource
    private BlackIpUtils blackIpUtils;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String ipAddress = getIpAddress(request);

        if (blackIpUtils.isBlackIp(ipAddress)) {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            response.getHeaders().setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
            return response.writeWith(Mono.just(response.bufferFactory().wrap(
                    "{\"errorCode\":\"-1\",\"errorMsg\":\"黑名单IP，禁止访问\"}".getBytes())));
        }

        return chain.filter(exchange);
    }

    private String getIpAddress(ServerHttpRequest request) {
        // 从请求头或其他位置获取客户端IP地址
        String ip = request.getHeaders().getFirst("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeaders().getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeaders().getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddress().getAddress().getHostAddress();
            if ("127.0.0.1".equals(ip)) {
                // 根据网卡取本机配置的 IP
                try {
                    ip = java.net.InetAddress.getLocalHost().getHostAddress();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        // 多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        if (ip == null) {
            return "127.0.0.1";
        }
        return ip;
    }

    @Override
    public int getOrder() {
        // 设置过滤器的顺序，数值越小优先级越高
        return Ordered.HIGHEST_PRECEDENCE;
    }
}